﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace KATS_Client.Client
{
    /// <summary>
    /// An object on a file system
    /// </summary>
    public class FileSystemObject
    {
        /// <summary>Return a clone of this object</summary>
        /// <returns></returns>
        public FileSystemObject Clone()
        {
            FileSystemObject fso = new FileSystemObject(this.ToXML());
            return fso;
        }

        /// <summary>
        /// The location of the file
        /// </summary>
        private string location = string.Empty;

        /// <summary>
        /// The location of the file
        /// </summary>
        public string Location
        {
            get { return this.location; }
            private set { this.location = value; }
        }
        
        /// <summary>
        /// Is the object remote?
        /// </summary>
        private bool isRemote = false;

        /// <summary>
        /// Is the object remote?
        /// </summary>
        public bool IsRemote
        {
            get { return this.isRemote; }
            private set { this.isRemote = value; }
        }

        /// <summary>
        /// Is the file local?
        /// </summary>
        public bool IsLocal
        {
            get { return !IsRemote; }
            private set { this.IsRemote = !value; }
        }

        /// <summary>
        /// The type of file system object is
        /// </summary>
        public FileSystemObjectTypes objectType;

        /// <summary>
        /// Is this a file?
        /// </summary>
        public bool IsFile
        {
            get
            {
                if (objectType == FileSystemObjectTypes.File)
                    return true;
                else
                    return false;
            }
        }

        /// <summary>
        /// Is this a directory?
        /// </summary>
        public bool IsDirectory
        {
            get
            {
                if (objectType == FileSystemObjectTypes.Directory)
                    return true;
                else
                    return false;
            }
        }


        /// <summary>
        /// Is this folder the My Computer folder
        /// </summary>
        public bool IsMyComputer
        {
            get
            {
                if (Location == string.Empty)
                    return true;
                return false;
            }
        }



        /// <summary>
        /// Get the current name of the object
        /// </summary>
        public string Name
        {
            get
            {
                if (this.IsMyComputer)
                {
                    if (this.IsRemote)
                        return "Remote Computer";
                    else
                        return "Local Computer";
                }
                else if (objectType == FileSystemObjectTypes.Directory)
                {
                    System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(Location);
                    return di.Name;
                }
                else if (objectType == FileSystemObjectTypes.File)
                {
                    System.IO.FileInfo fi = new System.IO.FileInfo(Location);
                    return fi.Name;
                }
                else
                {
                    return Location;
                }
            }
        }

        /// <summary>
        /// The size of this object
        /// </summary>
        private long _Size = -1;

        /// <summary>
        /// The size of this object
        /// </summary>
        public long Size
        {
            get
            {
                if (_Size < 0)
                {
                    GetSize();
                }
                return _Size;
            }
            set
            {
                _Size = value;
            }
        }

        /// <summary>
        /// Get the size of this object
        /// </summary>
        public void GetSize()
        {
            _Size = Client.FileActions.Size(this);
        }

        /// <summary>
        /// Get the parent directory for this object
        /// </summary>
        public FileSystemObject Parent
        {
            get
            {
                if (IsDirectory)
                {
                    System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(Location);
                    return new FileSystemObject(di.Parent.FullName, this.IsRemote, FileSystemObjectTypes.Directory);
                }
                else if (IsFile)
                {
                    System.IO.FileInfo fi = new System.IO.FileInfo(Location);
                    return new FileSystemObject(fi.Directory.FullName, this.IsRemote, FileSystemObjectTypes.Directory);
                }
                else
                {
                    return this;
                }
            }
        }


        /// <summary>
        /// Get this object represented as XML
        /// </summary>
        /// <returns>XML</returns>
        public XElement ToXML()
        {
            XElement e = new XElement("FileSystemObject",
                new XElement("Location", Location),
                new XElement("Remote", IsRemote.ToString()),
                new XElement("Type",objectType.ToString())
                );
            return e;
        }

        /// <summary>
        /// A string that represents this object
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("\nWhere: {0}\n\tRemote: {1}\n\tType: {2}", Location, IsRemote, objectType.ToString());
        }

        /// <summary>
        /// Get the hash code for this object
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return ToString().GetHashCode();
        }

        /// <summary>
        /// Does this object equals the other object
        /// </summary>
        /// <param name="obj">The object to compare</param>
        /// <returns>Is equals?</returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;
            return this.ToString() == obj.ToString();
        }

        /// <summary>
        /// Create a file system object
        /// </summary>
        /// <param name="Location">The location</param>
        /// <param name="isRemote">Is Remote?</param>
        /// <param name="type">Type of file? [HDD, Directory, file?]</param>
        public FileSystemObject(string Location, bool isRemote, FileSystemObjectTypes type)
        {
            this.Location = Location;
            this.IsRemote = isRemote;
            this.objectType = type;
        }

        /// <summary>
        /// Create the file system object from XML representation
        /// </summary>
        /// <param name="XML">The XML</param>
        public FileSystemObject(XElement XML)
        {
            this.Location = XML.Element("Location").Value;
            this.IsRemote = bool.Parse(XML.Element("Remote").Value);
            this.objectType = (FileSystemObjectTypes)Enum.Parse(typeof(FileSystemObjectTypes), XML.Element("Type").Value, true);
        }
    }
}
